#include "strategy.hpp"
#include "types.h"

namespace Trade {

struct Strategy00 : public Strategy
{
  Strategy00(MoneyTree* mt, TJM* tjm) noexcept
    : Strategy(mt, tjm)
  {
  }
  ~Strategy00() {}

  int reduce_time_ = 0;
  price_t reduce_price_ = 0;

  int money_tree() noexcept;

  bool is_good_enter_spot(const dir_t d) const noexcept;
  bool is_good_expected_space(const dir_t d,
                              const bool good_enter) const noexcept;
  bool is_good_timer(const dir_t d, const time_t ts) const noexcept;
  bool reached_target_space(const dir_t d) const noexcept;
  bool visual_dir_against_dir(const dir_t d) const noexcept;
  bool is_strong_opportunity(const dir_t d) const noexcept;

  price_t calculate_reduce_price() noexcept;
  price_t calculate_close_price() noexcept;
  price_t calculate_min_win_price() noexcept;
  price_t calculate_stop_win_price() noexcept;
  price_t calculate_stop_loss_price() noexcept;
  bool risk_is_good_to_me(const price_t risk) const noexcept;

  int jerry_in_dangerous() noexcept;

  int tom_run(const dir_t d, const price_t enter) noexcept;
  int jerry_run(const dir_t d, const price_t enter) noexcept;
  int mickey_run(const dir_t d, const price_t enter) noexcept;
  int tom_stop() noexcept;
  int jerry_stop() noexcept;
  int mickey_stop() noexcept;

  int should_add_position() noexcept;
  int should_deduce_position() noexcept;
  int get_open_volume() noexcept;
  int get_close_volume() noexcept;
  bool should_close_all_position() noexcept;
  bool can_i_safe_myself() noexcept;
  int safe_me_please() noexcept;

  event_t on_order_open(const OrderPtr& o, const DealPtr& deal) noexcept;
  event_t on_order_close(const OrderPtr& o, const DealPtr& deal) noexcept;

  int earned_good_enough_space(const dir_t d) const noexcept;
  int pet_time_outed(const dir_t d) const noexcept;

  int on_open(const Trigger* trigger) noexcept;
  int on_close(const Trigger* trigger) noexcept;
  int on_close_stop_win(const Trigger* trigger) noexcept;
  int on_close_stop_loss(const Trigger* trigger) noexcept;
  int on_close_min_win(const Trigger* trigger) noexcept;

  int on_mark_price_up(const Trigger* trigger) noexcept;
  int on_mark_price_dn(const Trigger* trigger) noexcept;
  int on_mark_timer_out(const Trigger* trigger) noexcept;

private:
  int on_mark_price_(const Trigger* trigger) noexcept;
  int close_half_or_all_(const bool dangerous,
                         const bool reached_min_win,
                         const bool keep_tom,
                         const dir_t d,
                         const price_t hpx) noexcept;
  int set_close_min_win_() noexcept;
  int set_close_stop_loss_() noexcept;
  int set_close_stop_win_() noexcept;
  int set_close_(const price_t hpx) noexcept;

  int set_mark_price_(const dir_t d, const price_t hpx) noexcept;
  int deduce_position_() noexcept;
  int try_jerry_() noexcept;
  void debug_history() noexcept;
};

}